<!-- RichTextEditor.vue -->
<template>
    <div class="rich-text-editor">
        <h2>📝 富文本编辑器</h2>

        <!-- 操作按钮 -->
        <div class="controls">
            <button class="save" @click="saveContent">💾 保存内容</button>
            <button class="load" @click="loadContent">🔁 加载已保存内容</button>
            <button class="random" @click="loadRandomArticle">🎲 随机加载一篇文章</button>
            <button class="clear" @click="clearContent">🗑️ 清空</button>
        </div>

        <!-- 工具栏 -->
        <div class="toolbar">
            <button v-for="level in [1, 2, 3]" :key="'h' + level" :class="{ active: headingActive === level }"
                @click="setHeading(level)">
                H{{ level }}
            </button>

            <button :class="{ active: isFormatActive('bold') }" @click="execCommand('bold')">
                <b>B</b>
            </button>

            <button :class="{ active: isFormatActive('italic') }" @click="execCommand('italic')">
                <i>I</i>
            </button>

            <button :class="{ active: inUnorderedList }" @click="execCommand('insertUnorderedList')">
                📝 UL
            </button>

            <button :class="{ active: inOrderedList }" @click="execCommand('insertOrderedList')">
                🔢 OL
            </button>

            <input type="color" ref="colorPicker" @input="setColor" style="display: none" />
            <button @click="$refs.colorPicker.click()">🎨 颜色</button>
        </div>

        <!-- 编辑区 -->
        <div class="editor" contenteditable="true" ref="editor" @keydown="handleKeydown" @input="updateContent"
            @mouseup="updateButtonStates" @keyup="updateButtonStates" @focus="updateButtonStates"
            @click="updateButtonStates"></div>

        <!-- 预览 -->
        <div class="preview">
            <h4>HTML 内容预览：</h4>
            <pre>{{ htmlContent }}</pre>
        </div>
    </div>
</template>

<script setup>
import { ref, nextTick } from 'vue';

// 编辑器引用
const editor = ref(null);
const colorPicker = ref(null);

// 当前内容
const htmlContent = ref('');

// 格式状态
const headingActive = ref(0);
const inUnorderedList = ref(false);
const inOrderedList = ref(false);

// 当前文章 ID（用于保存/加载）
const currentArticleId = ref('user-draft');

// ========== 📚 Mock 文章数据 ==========
const mockArticles = [
    {
        id: 'article-1',
        title: 'Vue 3 新特性介绍',
        content: `
        <h1 style="color: #1a73e8;">Vue 3 新特性</h1>
        <p>Vue 3 引入了以下重要更新：</p>
        <ul>
          <li><b>Composition API</b>：更灵活的逻辑复用</li>
          <li><i>Teleport</i>：组件渲染到任意位置</li>
          <li>更好的 <span style="color: #e91e63;">TypeScript</span> 支持</li>
        </ul>
        <p>是现代前端开发的优秀选择！</p>
      `,
    },
    {
        id: 'article-2',
        title: '健康生活小贴士',
        content: `
        <h2 style="color: #388e3c;">健康生活指南</h2>
        <p>每天坚持以下几点，保持身心健康：</p>
        <ol>
          <li>✅ 每天步行 <b>8000 步</b></li>
          <li>✅ 喝够 <span style="color: #1976d2;">2L 水</span></li>
          <li>✅ 睡眠不少于 <i>7 小时</i></li>
        </ol>
        <p>坚持就是胜利！💪</p>
      `,
    },
    {
        id: 'article-3',
        title: '旅行计划清单',
        content: `
        <h3 style="color: #f57c00;">云南旅行计划</h3>
        <p>出发时间：<b>2025年4月</b></p>
        <ul>
          <li>📍 大理：洱海骑行</li>
          <li>📍 丽江：古城漫步</li>
          <li>📍 香格里拉：普达措国家公园</li>
        </ul>
        <p>预算：<span style="color: #d32f2f;">¥5000</span> 左右</p>
      `,
    },
];

// ========== 💾 模拟数据库（持久化存储）==========
const mockDatabase = {};

// 保存内容
const mockSaveContent = async (id, content) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            mockDatabase[id] = content;
            console.log(`[Mock API] 保存成功: ${id}`);
            resolve({ success: true, data: { id, updatedAt: new Date() } });
        }, 300);
    });
};

// 加载内容
const mockLoadContent = async (id) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            const content = mockDatabase[id] || null;
            resolve({ success: !!content, data: content });
        }, 300);
    });
};

// ========== ✏️ 编辑器核心功能 ==========
const execCommand = (command, value = null) => {
    document.execCommand(command, false, value);
    editor.value.focus();
    updateButtonStates();
    updateContent();
};

// 设置标题
const setHeading = (level) => {
    const tag = `<h${level}>`;
    document.execCommand('formatBlock', false, tag);
    updateButtonStates();
    updateContent();
};

// 设置颜色
const setColor = (e) => {
    document.execCommand('foreColor', false, e.target.value);
    updateButtonStates();
    updateContent();
};

// 判断加粗、斜体等（queryCommandState 可靠）
const isFormatActive = (command) => {
    if (['bold', 'italic'].includes(command)) {
        try {
            return document.queryCommandState(command);
        } catch (e) {
            return false;
        }
    }
    return false;
};

// 更新按钮高亮状态（标题 + 列表）
const updateButtonStates = () => {
    nextTick(() => {
        const selection = window.getSelection();
        if (!selection.rangeCount) return;

        const range = selection.getRangeAt(0);
        let container = range.commonAncestorContainer;
        if (container.nodeType === 3) container = container.parentNode;

        // --- 检查标题 ---
        let parent = container;
        let level = 0;
        while (parent && parent !== editor.value) {
            if (['H1', 'H2', 'H3'].includes(parent.tagName)) {
                level = parseInt(parent.tagName[1]);
                break;
            }
            parent = parent.parentNode;
        }
        headingActive.value = level;

        // --- 检查列表 ---
        const checkAncestor = (node, tag) => {
            while (node && node !== editor.value) {
                if (node.tagName === tag) return true;
                node = node.parentNode;
            }
            return false;
        };

        inUnorderedList.value = checkAncestor(container, 'UL');
        inOrderedList.value = checkAncestor(container, 'OL');
    });
};

// 更新内容
const updateContent = () => {
    nextTick(() => {
        htmlContent.value = editor.value.innerHTML;
    });
};

// 回车换行处理
const handleKeydown = (e) => {
    if (e.key === 'Enter' && e.shiftKey) {
        document.execCommand('insertLineBreak');
        e.preventDefault();
    }
};

// ========== 📥 业务方法 ==========
const saveContent = async () => {
    await updateContent();
    const res = await mockSaveContent(currentArticleId.value, htmlContent.value);
    if (res.success) {
        alert(`✅ 内容已保存（ID: ${currentArticleId.value}）`);
    }
};

const loadContent = async () => {
    const res = await mockLoadContent(currentArticleId.value);
    if (res.success && res.data) {
        editor.value.innerHTML = res.data;
        htmlContent.value = res.data;
        updateButtonStates();
        alert('✅ 已加载你上次保存的内容！');
    } else {
        alert('❌ 未找到已保存的内容');
    }
};

const loadRandomArticle = () => {
    const randomArticle = mockArticles[Math.floor(Math.random() * mockArticles.length)];
    editor.value.innerHTML = randomArticle.content;
    htmlContent.value = randomArticle.content;
    updateButtonStates();
    currentArticleId.value = `draft-from-${randomArticle.id}`;
    alert(`🎲 已加载：《${randomArticle.title}》\n可继续编辑并保存`);
};

const clearContent = () => {
    editor.value.innerHTML = '';
    htmlContent.value = '';
    updateButtonStates();
};
</script>

<style lang="scss" scoped>
// 🎨 颜色变量
$primary: #007cba;
$success: #4caf50;
$info: #2196f3;
$warning: #ff9800;
$danger: #f44336;
$text: #333;
$border: #ddd;
$bg-light: #f5f7fa;
$bg-editor: #ffffff;
$pre-bg: #f9f9f9;
$toolbar-bg: #fbfbfb;
$shadow: rgba(0, 0, 0, 0.1);
$radius: 6px;

.rich-text-editor {
    width: 750px;
    margin: 20px auto;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    box-shadow: 0 2px 10px $shadow;
    border-radius: $radius;
    overflow: hidden;
    background: $bg-editor;

    .controls {
        padding: 12px;
        background: $bg-light;
        border-bottom: 1px solid $border;
        display: flex;
        gap: 10px;
        flex-wrap: wrap;

        button {
            padding: 8px 14px;
            font-size: 14px;
            border: none;
            border-radius: $radius;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 6px;
            font-weight: 600;
            color: white;
            transition: all 0.2s;

            &.save {
                background: $success;
            }

            &.load {
                background: $info;
            }

            &.random {
                background: $warning;
            }

            &.clear {
                background: $danger;
            }

            &:hover {
                transform: translateY(-1px);
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            }
        }
    }

    .toolbar {
        padding: 10px;
        background-color: $toolbar-bg;
        border-bottom: 1px solid $border;
        display: flex;
        flex-wrap: wrap;
        gap: 6px;

        button {
            padding: 6px 10px;
            border: 1px solid $border;
            background: white;
            cursor: pointer;
            font-weight: 600;
            font-size: 14px;
            border-radius: 4px;
            transition: all 0.2s;

            &:hover {
                background-color: darken($toolbar-bg, 5%);
                border-color: lighten($border, 10%);
            }

            &.active {
                background-color: $primary;
                color: white;
                border-color: $primary;
                box-shadow: 0 0 0 1px rgba($primary, 0.3);
            }
        }
    }

    .editor {
        min-height: 220px;
        padding: 16px;
        background: $bg-editor;
        outline: none;
        line-height: 1.6;
        font-size: 15px;
        color: $text;

        &:focus {
            box-shadow: 0 0 0 2px rgba($primary, 0.2);
        }
    }

    .preview {
        padding: 16px;
        background-color: $pre-bg;
        border-top: 1px solid $border;
        font-size: 13px;
        color: darken($text, 20%);
        max-height: 200px;
        overflow-y: auto;

        h4 {
            margin: 0 0 8px 0;
            color: $text;
            font-weight: 600;
        }
    }
}
</style>